﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using DataAnnotationsExtensions;
using Eff.Extensions;
using Eff.Security;
using Eff.Utils.Attributes;
using Redmine.Core.Enums.User;
using Redmine.Core.Locals;
using Redmine.Core.Repositories;
using UnitOfWork.Validation;


namespace Redmine.Core.Entities
{
    public class User
    {
        #region DbField
        /// <summary>
        /// id自增
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 登录名
        /// </summary>
        [Display(ResourceType = typeof(Lang), Name = "Field_LoginName"), Required, MaxLength(30),
        RegularExpression(@"^[a-z0-9_\-@\.]*$"),
        Uniqueness("Users", ErrorMessageResourceType = typeof(Lang), ErrorMessageResourceName = "ErrMsg_Exists")]
        public string LoginName { get; set; }


        /// <summary>
        /// 密码
        /// </summary>
        [Display(ResourceType = typeof(Lang), Name = "Field_PasswordHashed")]
        [Required]
        public string PasswordHashed { get; set; }

        /// <summary>
        /// 名
        /// </summary>
        [Display(ResourceType = typeof(Lang), Name = "Field_FirstName")]
        [Required]
        [MaxLength(30)]
        public string FirstName { get; set; }

        /// <summary>
        /// 姓
        /// </summary>
        [Display(ResourceType = typeof(Lang), Name = "Field_LastName")]
        [Required]
        [MaxLength(30)]
        public string LastName { get; set; }

        /// <summary>
        /// 邮件地址
        /// </summary>
        [Display(ResourceType = typeof(Lang), Name = "Field_Mail")]
        [Email(ErrorMessageResourceType = typeof(Lang), ErrorMessageResourceName = "ErrMsg_EmailErr")]
        [Uniqueness("Users", ErrorMessageResourceType = typeof(Lang), ErrorMessageResourceName = "ErrMsg_Exists")]
        [MaxLength(60)]
        public string Mail { get; set; }

        /// <summary>
        /// 是否管理员
        /// </summary>
        [Display(ResourceType = typeof(Lang), Name = "Field_IsAdmin")]
        public bool IsAdmin { get; set; }

        /// <summary>
        /// 审核状态
        /// </summary>
        [Display(ResourceType = typeof(Lang), Name = "Field_Status")]
        [Range(0, 3)] //todo: 提示
        public short Status { get; set; }

        /// <summary>
        /// 最后登录时间
        /// </summary>
        [Display(ResourceType = typeof(Lang), Name = "Field_LastLoginTime")]
        public DateTime LastLoginTime { get; set; }

        /// <summary>
        /// 语言
        /// </summary>
        [Display(ResourceType = typeof(Lang), Name = "Field_Language")]
        public string Language { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public int AuthSourceId { get; set; }

        /// <summary>
        /// 建立时间
        /// </summary>
        [Display(ResourceType = typeof(Lang), Name = "Field_CreatedOn")]
        public DateTime CreatedOn { get; set; }

        /// <summary>
        /// 更新时间
        /// </summary>
        [Display(ResourceType = typeof(Lang), Name = "Field_UpdatedOn")]
        public DateTime UpdatedOn { get; set; }

        /// <summary>
        /// 用户类型 User 'AnonymousUser'
        /// </summary>
        [Display(ResourceType = typeof(Lang), Name = "Field_Type")]
        public string Type { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Display(ResourceType = typeof(Lang), Name = "Field_IdentityUrl")]
        public string IdentityUrl { get; set; }

        /// <summary>
        /// 邮件通知方式
        /// </summary>
        [Display(ResourceType = typeof(Lang), Name = "Field_MailNotification")]
        [Range(0, 5)] //todo: 无效值提示
        public short MailNotification { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string Salt { get; set; }

        public virtual ICollection<Member> Members { get; set; }

        //        public User()
        //        {
        //            LoginName = LoginName ?? string.Empty;
        //            PasswordHashed = PasswordHashed ?? string.Empty;
        //            FirstName = FirstName ?? string.Empty;
        //            LastName = LastName ?? string.Empty;
        //            Mail = Mail ?? string.Empty;
        //            //
        //            //             self.login ||= ''
        //            //    self.hashed_password ||= ''
        //            //    self.firstname ||= ''
        //            //    self.lastname ||= ''
        //            //    self.mail ||= ''
        //        } 
        #endregion

        [Display(ResourceType = typeof(Lang), Name = "Field_PasswordHashed")]
        [Required]
        [DataType(DataType.Password)]
        [NotMapped]
        public string Password { get; set; }

        [Display(ResourceType = typeof(Lang), Name = "Field_PasswordConfirm")]
        [Required]
        [EqualTo("Password", ErrorMessageResourceType = typeof(Lang), ErrorMessageResourceName = "ErrMsg_NotEqual")]
        [DataType(DataType.Password)]
        [NotMapped]
        public string PasswordConfirm
        {
            set
            {
                _passwordConfirm = value;
                PasswordHashed = Md5.Encode(value);
            }
            get { return _passwordConfirm; }
        }
        private string _passwordConfirm;


        /// <summary>
        /// 获取显示名称
        /// </summary>
        /// <param name="format"></param>
        /// <param name="settingRepository"></param>
        /// <returns></returns>
        public string GetDisplayName(ISettingRepository settingRepository, UserFormat format = UserFormat.Default)
        {
            if (format == UserFormat.Default)
                format = (UserFormat)settingRepository["user_format"].AsShort();
            return string.Format(format.GetAttachedData<string>(), FirstName, LastName, LoginName);
        }

        [NotMapped]
        public bool Logged { get { return true; } }

    }

    public class AnonymousUser : User
    {
        public new bool IsAdmin
        {
            get
            {
                return false;
            }
        }

        public new string GetDisplayName(ISettingRepository settingRepository, UserFormat format = UserFormat.Default)
        {
            return Lang.Label_UserAnonymous;
        }

        public new string Mail
        {
            get { return string.Empty; }
        }


    }
}
